#include <cstdio>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <thread>
#include <vector>
#include <genai/vision/image.h>
#include <gio/gio.h>

static void writeBinaryDataToFile(const std::string &filename,
                           const std::vector<char> &data) {
    std::ofstream outputFile(filename, std::ios::out | std::ios::binary | std::ios::trunc);
    if (!outputFile.is_open()) {
        std::cerr << "Failed to open file for writing." << std::endl;
        return;
    }

    // 写入数据到文件
    outputFile.write(data.data(), data.size());

    // 检查是否写入成功
    if (!outputFile.good()) {
        std::cerr << "Error occurred while writing to file." << std::endl;
    } else {
        std::cout << "Binary data has been written to file: " << filename
                  << std::endl;
    }

    // 关闭文件
    outputFile.close();
}

void callback(VisionImageResult *image_data, void *user_data) {
    int imageDataLength;
    const uint8_t* imageData = image_result_get_data(image_data, &imageDataLength);
    int imageWidth = image_result_get_size(image_data).width;
    int imageHeight = image_result_get_size(image_data).height;
    ImageFormat format = image_result_get_format(image_data);
    int index = image_result_get_index(image_data);
    int total = image_result_get_total(image_data);

    int errorcode = image_result_get_error_code(image_data);
    std::string errorMsg = image_result_get_error_message(image_data);


    std::vector<char> imagedata { imageData, imageData + imageDataLength };
    writeBinaryDataToFile("../test3.png", imagedata);

    int userData = *(int*)user_data;
    std::cout << "length " << imageDataLength
              << " width " << imageWidth
              << " height " << imageHeight
              << " format " << format << std::endl;
    std::cout << "index " << index
              << " total " << total
              << " errorCode " << errorcode
              << " errorMag " << errorMsg
              << " userdata " << userData << std::endl;
}

void test() {
    auto *loop_ = g_main_loop_new(nullptr, false);

    GenAiImageSession *session = genai_image_create_session();
    int initRet = genai_image_init_session(session);
    fprintf(stderr, "init return value %i\n", initRet);

    ImageConfig *config = image_config_create();
    image_config_set_generation_number(config, 1);
    image_config_set_style(config, "写实风格");
    image_config_set_size(config, ImageSize{1280, 720});
    genai_image_set_config(session, config);

    bool imageNumber = genai_image_get_supported_image_number(session);
    std::cout << "supported image number " << imageNumber << std::endl;

    int sizeNumber;
    const ImageSize* imageSize = genai_image_get_supported_image_size(session, &sizeNumber);
    int i = 0;
    while (i < sizeNumber) {
        std::cout << "supported image size width " << imageSize[i].width
                  << " height " << imageSize[i].height << std::endl;
        ++i;
    }

    int styleNumber;
    int j = 0;
    const char** imageStyle = genai_image_get_supported_image_style(session, &styleNumber);
    while (j < styleNumber) {
        std::cout << "supported image style " << imageStyle[j] << std::endl;
        ++j;
    }

    int *a = new int();
    *a = 100;
    genai_image_result_set_callback(session, callback, a);

    genai_image_generate_image_async(session, "生成一张小狗的图片");

    g_main_loop_run(loop_);
}

int main() {
    test();
    return 0;
}
